package cn.wp.user.service.impl;

import cn.wp.basic.constant.PetHomeConstant;
import cn.wp.basic.constant.VerificationConstant;
import cn.wp.basic.exception.CustomException;
import cn.wp.basic.service.impl.BaseServiceImpl;
import cn.wp.basic.util.MD5Utils;
import cn.wp.basic.util.StrUtils;
import cn.wp.user.domain.LoginInfo;
import cn.wp.user.domain.User;
import cn.wp.user.dto.UserDto;
import cn.wp.user.mapper.LoginInfoMapper;
import cn.wp.user.mapper.UserMapper;
import cn.wp.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LoginInfoMapper loginInfoMapper;

    /**
     * 验证手机号
     * @param phone
     * @throws CustomException
     */
    @Override
    public void checkPhone(String phone) throws CustomException {
        User user = userMapper.findByPhone(phone);
        if (user != null){
            throw new CustomException("手机号码已存在！");
        }
    }


    @Override
    @Transactional
    public void register(UserDto userDto) throws CustomException {
        // 校验数据
        checkData(userDto);
        // 创建user对象
        User user = userDto2User(userDto);
        // 创建LoginInfo对象
        LoginInfo loginInfo = createLoginInfo(user);
        // 保存t_logininfo表，保存了才有logininfo_id
        loginInfoMapper.save(loginInfo);
        // 设置logininfo
        user.setLoginInfo(loginInfo);
        // 保存t_user表
        userMapper.save(user);
    }

    @Override
    public User loadByLoginInfoId(Long id) {
        return userMapper.loadByLoginInfoId(id);
    }

    /**
     * 创建LoginInfo对象
     * @param user
     * @return
     */
    private LoginInfo createLoginInfo(User user) {
        LoginInfo loginInfo = new LoginInfo();
        BeanUtils.copyProperties(user, loginInfo);
        loginInfo.setType(PetHomeConstant.ADMIN);
        return loginInfo;
    }

    /**
     * 创建user对象
     * @param userDto
     * @return
     */
    private User userDto2User(UserDto userDto) {
        User user = new User();
        user.setPhone(userDto.getPhone());
        // 生成动态盐值
        user.setSalt(StrUtils.getComplexRandomString(10));
        // 密码加密
        user.setPassword(MD5Utils.encrypByMd5(userDto.getPassword() + user.getSalt()));
        return user;
    }

    private void checkData(UserDto userDto) throws CustomException {
        if (StringUtils.isEmpty(userDto.getPhone())){
            throw new CustomException("手机号不能为空！");
        }
        // 校验手机号
        checkPhone(userDto.getPhone());

        // 校验验证码
        if (StringUtils.isEmpty(userDto.getCode())){
            throw new CustomException("验证码不能为空！");
        }
        String codeVlue = (String) redisTemplate.opsForValue().get(userDto.getPhone() + ":" + VerificationConstant.USER_REG);
        if (StringUtils.isEmpty(codeVlue)){
            throw new CustomException("验证码已失效，请重新获取！");
        }
        if (!userDto.getCode().equals(codeVlue.split(":")[0])){
            throw new CustomException("验证码错误！");
        }

        // 校验密码
        if (StringUtils.isEmpty(userDto.getPassword())){
            throw new CustomException("密码必填！");
        }
        if (StringUtils.isEmpty(userDto.getConfigPassword())){
            throw new CustomException("确认密码必填!!");
        }
        if (!userDto.getPassword().equals(userDto.getConfigPassword())){
            throw new CustomException("两次密码不一致！");
        }

        LoginInfo loginInfo = loginInfoMapper.loadByPhoneAndType(userDto.getPhone(), PetHomeConstant.HOME);
        if (loginInfo != null){
            throw new CustomException("手机号已被注册！");
        }
    }
}
